package com.mentalhealthplatform.global.rbac.service.entity;

import com.mentalhealthplatform.global.rbac.dto.normal.ButtonComponentDTO;
import com.mentalhealthplatform.global.rbac.model.ButtonComponent;
import com.mentalhealthplatform.global.rbac.model.Endpoint;
import com.mentalhealthplatform.global.rbac.model.Menu;
import com.mentalhealthplatform.global.rbac.repository.ButtonComponentRepository;
import com.mentalhealthplatform.global.rbac.repository.EndpointRepository;
import com.mentalhealthplatform.global.rbac.repository.MenuRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ButtonComponentService {

    @Autowired
    private ButtonComponentRepository buttonRepository;

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private EndpointRepository endpointRepository;

    public ButtonComponentDTO createButton(ButtonComponentDTO buttonDTO) {
        // 创建 ButtonComponent 实体
        ButtonComponent button = new ButtonComponent(
                buttonDTO.getIdentifier(),
                buttonDTO.getDisplayName(),
                buttonDTO.getDescription()
        );

        // 设置其他属性
        button.setOrderNum(buttonDTO.getOrderNum());
        button.setVisible(buttonDTO.isVisible());
        button.setStatus(buttonDTO.isStatus());

        // 获取父菜单并设置 parentMenu
        if (buttonDTO.getParentId() != null) {
            Optional<Menu> parentMenu = menuRepository.findById(buttonDTO.getParentId());
            if (parentMenu.isPresent()) {
                button.setParentMenu(parentMenu.get());
            } else {
                throw new IllegalArgumentException("Parent menu not found with ID: " + buttonDTO.getParentId());
            }
        }

        // 处理 endpointIds
        Set<Long> endpointIds = buttonDTO.getEndpointIds();
        if (endpointIds != null && !endpointIds.isEmpty()) {
            // 查找相关的 Endpoint 实体对象
            Set<Endpoint> endpoints = endpointRepository.findByIdIn(endpointIds);

            // 检查是否有有效的 endpoint，如果没有则抛出合适的异常
            if (endpoints.isEmpty()) {
                throw new IllegalArgumentException("No valid endpoints found for the provided IDs: " + endpointIds);
            }

            // 设置有效的 endpoints
            button.setEndpoints(endpoints);
        }

        // 保存按钮并返回对应的 DTO
        button = buttonRepository.save(button);

        // 返回映射后的 DTO
        return new ButtonComponentDTO(button);
    }


    public ButtonComponentDTO updateButton(Long id, ButtonComponentDTO buttonDTO) {
        ButtonComponent button = buttonRepository.findById(id).orElseThrow(() -> new RuntimeException("Button not found"));
        button.setDisplayName(buttonDTO.getDisplayName());
        button.setDescription(buttonDTO.getDescription());
        button.setOrderNum(buttonDTO.getOrderNum());
        button.setVisible(buttonDTO.isVisible());
        button.setStatus(buttonDTO.isStatus());

        // 获取父菜单并设置 parentMenu
        Optional<Menu> parentMenu = menuRepository.findById(buttonDTO.getParentId());
        if (parentMenu.isPresent()) {
            button.setParentMenu(parentMenu.get());
        } else {
            throw new IllegalArgumentException("Parent menu not found with ID: " + buttonDTO.getParentId());
        }

        // 处理 endpointIds
        Set<Long> endpointIds = buttonDTO.getEndpointIds();
        if (endpointIds != null && !endpointIds.isEmpty()) {
            // 查找相关的 Endpoint 实体对象
            Set<Endpoint> endpoints = endpointRepository.findByIdIn(endpointIds);

            // 检查是否有有效的 endpoint，如果没有则抛出合适的异常
            if (endpoints.isEmpty()) {
                throw new IllegalArgumentException("No valid endpoints found for the provided IDs: " + endpointIds);
            }

            // 设置有效的 endpoints
            button.setEndpoints(endpoints);
        }else {
            // 如果 endpointIds 为空，清空已有的 endpoints
            button.setEndpoints(Collections.emptySet());
        }

        button = buttonRepository.save(button);

        return new ButtonComponentDTO(button);
    }

    public void deleteButton(Long id) {
        buttonRepository.deleteById(id);
    }

    public void toggleButtonStatus(Long id) {
        ButtonComponent button = buttonRepository.findById(id).orElseThrow(() -> new RuntimeException("Button not found"));
        button.toggleStatus();
        buttonRepository.save(button);
    }

    public void toggleButtonVisibility(Long id) {
        ButtonComponent button = buttonRepository.findById(id).orElseThrow(() -> new RuntimeException("Button not found"));
        button.setVisible(!button.isVisible());
        buttonRepository.save(button);
    }

    public void associateEndpoints(Long buttonId, List<Long> endpointIds) {
        ButtonComponent button = buttonRepository.findById(buttonId).orElseThrow(() -> new RuntimeException("Button not found"));
        Set<Endpoint> endpoints = endpointIds.stream()
                .map(endpointId -> endpointRepository.findById(endpointId).orElseThrow(() -> new RuntimeException("Endpoint not found")))
                .collect(Collectors.toSet());
        button.getEndpoints().addAll(endpoints);
        buttonRepository.save(button);
    }

    public void unassociateEndpoints(Long buttonId, List<Long> endpointIds) {
        ButtonComponent button = buttonRepository.findById(buttonId).orElseThrow(() -> new RuntimeException("Button not found"));
        Set<Endpoint> endpoints = endpointIds.stream()
                .map(endpointId -> endpointRepository.findById(endpointId).orElseThrow(() -> new RuntimeException("Endpoint not found")))
                .collect(Collectors.toSet());
        button.getEndpoints().removeAll(endpoints);
        buttonRepository.save(button);
    }
}
